/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui;

import gnu.io.CommPortIdentifier;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import org.apache.log4j.Logger;

import who.tmap.digitizer.ConfigPair;
import who.tmap.digitizer.DigitizerService;
import who.tmap.digitizer.impl.DigitizerConfig;
import who.tmap.digitizer.impl.DigitizerServiceImpl;

/**
 * @author mathieu bolletta
 *
 */
public class JPanelDigitizer extends JPanel implements DigitizerConfig {
	
    private static Logger logger = Logger.getLogger(JPanelDigitizer.class);  
	
	private DigitizerService ds =DigitizerServiceImpl.getInstance();
	
	private ButtonGroup coordinatesGroup;
	
	private JTabbedPane jTabbedPaneMain;
	
	// Coordinates system GUI components
	private JPanel jPanelrelativeCoordinates;
	private JTextField jTextFieldMinX;
	private JTextField jTextFieldMaxX;
	private JTextField jTextFieldMinY;
	private JTextField jTextFieldMaxY;
	private JLabel jLabelPicture;
	
	// Serial port configuration GUI components
	private JPanel jPanelSerialPort;
	
	// Communication port to use
	private JComboBox jComboBoxPortSelection;
	
	// Baud rate to use
	private JComboBox jComboBoxPortSpeed;
	private JComboBox jComboBoxDataBits;	
	private JComboBox jComboBoxParity;
	private JComboBox jComboBoxStopBits;
	
	// Data layout
	private JPanel jPanelDataLayout;
	private JTextField jTextFieldSeparator;	
	private JComboBox jComboBoxFieldSeparator;
	private JTextField jTextFieldLineSeparator;
	private JComboBox jComboBoxLineSeparator;
	private JPanel jPanelButtonsConfig;
	private JTextField jTextFieldNewPoint;
	private JTextField jTextFieldClosePolygon;
	
	public JPanelDigitizer() {
		super( new GridBagLayout() );
		
		getContainer();
	}
	
	public JPanel getContainer() {
		
		if ( jTabbedPaneMain == null) {
			
			GridBagConstraints cc =new GridBagConstraints();
			jTabbedPaneMain =new JTabbedPane(JTabbedPane.RIGHT);
			
			jTabbedPaneMain.add("Coordinates System", getJPanelRelativeCoordinates() );
			jTabbedPaneMain.add("Device Configuration", getJPanelSerialPort() );
			jTabbedPaneMain.add("Data Format", getJPanelDataFormatLayout() );		
			
			cc.gridx =0;
			cc.gridy =0;
			cc.weightx =.5;
			cc.weighty =.5;
			cc.gridwidth =2;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.BOTH;
			add(jTabbedPaneMain, cc);
	
		}
		return this;
	}
	

	private JPanel getJPanelSerialPort() {
		
		if ( jPanelSerialPort == null ) {
			jPanelSerialPort =new JPanel();
			jPanelSerialPort.setLayout( new GridBagLayout() );
			jPanelSerialPort.setBorder( BorderFactory.createEmptyBorder(5, 5, 5, 5) );
			GridBagConstraints cc =new GridBagConstraints();
			
			cc.gridx =0;
			cc.gridy =0;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.VERTICAL;
			jPanelSerialPort.add( new JLabel( "Communication port" ), cc );
			
			cc.gridx =0;
			cc.gridy =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( getJComboBoxPortSelection(), cc );
			
			cc.gridx =0;
			cc.gridy =2;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.CENTER;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( Box.createVerticalStrut( 15 ), cc );
			
			cc.gridx =0;
			cc.gridy =3;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( new JLabel( "Baud rate" ), cc );
			
			cc.gridx =0;
			cc.gridy =4;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( getJComboBoxPortSpeed(), cc );
			
			cc.gridx =0;
			cc.gridy =5;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.CENTER;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( Box.createVerticalStrut( 15 ), cc );
			
			cc.gridx =0;
			cc.gridy =6;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( new JLabel( "Data Bits" ), cc );
			
			cc.gridx =0;
			cc.gridy =7;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( getJComboBoxDataBits(), cc );
			
			cc.gridx =0;
			cc.gridy =8;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.CENTER;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( Box.createVerticalStrut( 15 ), cc );	
			
			cc.gridx =0;
			cc.gridy =9;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( new JLabel( "Parity" ), cc );
			
			cc.gridx =0;
			cc.gridy =10;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( getJComboBoxParity(), cc );	
			
			cc.gridx =0;
			cc.gridy =11;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.CENTER;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( Box.createVerticalStrut( 15 ), cc );
			
			cc.gridx =0;
			cc.gridy =12;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( new JLabel( "Stop bits" ), cc );
			
			cc.gridx =0;
			cc.gridy =13;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.gridwidth =1;
			cc.gridheight =1;
			cc.anchor =GridBagConstraints.WEST;
			cc.fill = GridBagConstraints.HORIZONTAL;
			jPanelSerialPort.add( getJComboBoxStopBits(), cc );
		}
		
		return jPanelSerialPort;
	}
	
	private JComboBox getJComboBoxStopBits() {
		if ( jComboBoxStopBits == null ) {
			jComboBoxStopBits =new JComboBox( STOP_BITS );
			
			jComboBoxStopBits.setSelectedIndex( getIdxForId( String.valueOf( ds.getStopBits() ), STOP_BITS ) );
		}
		
		return jComboBoxStopBits;
	}
	
	private JComboBox getJComboBoxDataBits() {
		if ( jComboBoxDataBits == null ) {
			jComboBoxDataBits =new JComboBox( DATA_BITS );
			
			jComboBoxDataBits.setSelectedIndex( getIdxForId( String.valueOf( ds.getDataBitsConfiguration() ), DATA_BITS ) );
		}
		
		return jComboBoxDataBits;
	}
	
	private JComboBox getJComboBoxParity() {
		if ( jComboBoxParity == null ) {
			jComboBoxParity =new JComboBox( PARITY );
			
			jComboBoxParity.setSelectedIndex( getIdxForId( String.valueOf( ds.getParity() ), PARITY ) );
		}
		
		return jComboBoxParity;
	}
	
	private JComboBox getJComboBoxPortSelection(){
		if ( jComboBoxPortSelection == null ){		
			
			try {
				String[] ports =getAvailablePorts();
				jComboBoxPortSelection = new JComboBox( ports );
				jComboBoxPortSelection.setSelectedItem( ds.getCommunicationPort() );
			} catch( Throwable e ) {
				jComboBoxPortSelection = new JComboBox();
				logger.error( e );
			}
		}
		
		return jComboBoxPortSelection;
	}
	
	private JComboBox getJComboBoxPortSpeed(){
		if( jComboBoxPortSpeed == null ){
			jComboBoxPortSpeed = new JComboBox( BAUD_RATES );
			
			jComboBoxPortSpeed.setSelectedItem( String.valueOf( ds.getBaudRate() ) );
		}
		
		return jComboBoxPortSpeed;	
	}
	
	private JPanel getJPanelRelativeCoordinates() {
		if( jPanelrelativeCoordinates == null ) {
			jPanelrelativeCoordinates =new JPanel();
			GridBagConstraints cc =new GridBagConstraints();
			
			jPanelrelativeCoordinates.setLayout( new GridBagLayout() );
			jPanelrelativeCoordinates.setBorder( BorderFactory.createTitledBorder("Relative Coordinates System") );

			cc.gridx =0;
			cc.gridy =0;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( new JLabel( " X Min" ), cc );
			
			jTextFieldMinX =new JTextField();
			cc.gridx =0;
			cc.gridy =1;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( jTextFieldMinX, cc );
			jTextFieldMinX.setText( String.valueOf( ds.getXMin() ) );
			
			cc.gridx =0;
			cc.gridy =2;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( Box.createVerticalStrut( 10 ), cc );
			
			cc.gridx =0;
			cc.gridy =3;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( new JLabel( " X Max" ), cc );
		
		    jTextFieldMaxX =new JTextField();
			cc.gridx =0;
			cc.gridy =4;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( jTextFieldMaxX, cc );
			jTextFieldMaxX.setText( String.valueOf( ds.getXMax() ) );				
			
			cc.gridx =1;
			cc.gridy =0;
			cc.gridheight =5;
			cc.gridwidth =1;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.BOTH;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( Box.createHorizontalStrut( 10 ), cc );
			
			cc.gridx =2;
			cc.gridy =0;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( new JLabel( " Y Min" ), cc );			

			jTextFieldMinY =new JTextField();
			
			cc.gridx =2;
			cc.gridy =1;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( jTextFieldMinY, cc );
			jTextFieldMinY.setText( String.valueOf( ds.getYMin() ) );
			
			cc.gridx =2;
			cc.gridy =2;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( Box.createVerticalStrut( 10 ), cc );
			
			cc.gridx =2;
			cc.gridy =3;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( new JLabel( " Y Max" ), cc );
			
		    jTextFieldMaxY =new JTextField();
		    //jTextFieldMaxY.setText("0.0");
			cc.gridx =2;
			cc.gridy =4;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( jTextFieldMaxY, cc );
			jTextFieldMaxY.setText( String.valueOf( ds.getYMax() ) );
			
			jLabelPicture =new JLabel();
			// Get a bitmap later - STL 2007.10.12
			//jLabelPicture.setIcon( new MiscHelper().getImageIcon( ".PNG" ) );
			cc.gridx =0;
			cc.gridy =5;
			cc.gridheight =1;
			cc.gridwidth =3;
			cc.weightx =.0;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.CENTER;
			cc.fill =GridBagConstraints.NONE;
			cc.insets =new Insets(5,5,5,5);
			jPanelrelativeCoordinates.add( jLabelPicture, cc );
			
		}
		
		return jPanelrelativeCoordinates;
	}
	
	private JPanel getJPanelDataFormatLayout() {
		if ( jPanelDataLayout == null ) {
			jPanelDataLayout =new JPanel();
			jPanelDataLayout.setLayout( new GridBagLayout() );
			GridBagConstraints cc =new GridBagConstraints();
			jPanelDataLayout.setBorder( BorderFactory.createTitledBorder( "Data Format Configuration" ) );
			
			cc.gridx =0;
			cc.gridy =0;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets = new Insets(5,5,5,5);
			jPanelDataLayout.add( new JLabel("Field separator"), cc );	
			
			cc.gridx =0;
			cc.gridy =1;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( getJComboBoxFieldSeparator(), cc );			
			
			cc.gridx =1;
			cc.gridy =0;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.fill =GridBagConstraints.HORIZONTAL;
			cc.insets = new Insets(5,5,5,5);
			jPanelDataLayout.add( new JLabel("Other field separator"), cc );
			
			jTextFieldSeparator =new JTextField();
			cc.gridx =1;
			cc.gridy =1;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( jTextFieldSeparator, cc );
			jTextFieldSeparator.setText( getJComboBoxFieldSeparator().getSelectedIndex() == OTHER_FIELD_SEPARATOR_ID 
																						 ? ds.getFieldSeparator() : "" );
			
			cc.gridx =0;
			cc.gridy =2;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( new JLabel("Line separator"), cc );
			
			cc.gridx =0;
			cc.gridy =3;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( getJComboBoxLineSeparator(), cc );
			
			cc.gridx =1;
			cc.gridy =2;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( new JLabel("Other line separator"), cc );
			
			jTextFieldLineSeparator =new JTextField();
			cc.gridx =1;
			cc.gridy =3;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add( jTextFieldLineSeparator, cc );
			jTextFieldLineSeparator.setText( getJComboBoxLineSeparator().getSelectedIndex() == OTHER_LINE_SEPARATOR_ID 
																							? ds.getLineSeparator() : "" );			
			
			cc.gridx =0;
			cc.gridy =4;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.5;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add(Box.createVerticalStrut( 15 ), cc);
			
			cc.gridx =0;
			cc.gridy =5;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.1;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.NORTHWEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelDataLayout.add(getJPanelButtonsConfig(),cc);
		}
		
		return jPanelDataLayout;
	}
	
	private JComboBox getJComboBoxFieldSeparator() {
		if ( jComboBoxFieldSeparator == null ) {
			jComboBoxFieldSeparator =new JComboBox( FIELD_SEPARATOR );
			
			int idx =getIdxForId( ds.getFieldSeparator() , FIELD_SEPARATOR );
			jComboBoxFieldSeparator.setSelectedIndex( idx != -1 ? idx : OTHER_FIELD_SEPARATOR_ID );
		}
		
		return jComboBoxFieldSeparator;
	}	
	
	private JComboBox getJComboBoxLineSeparator() {
		if ( jComboBoxLineSeparator == null ) {
			jComboBoxLineSeparator =new JComboBox( LINE_SEPARATOR );
			
			int idx =getIdxForId( ds.getLineSeparator() , LINE_SEPARATOR );
			jComboBoxLineSeparator.setSelectedIndex( idx != -1 ? idx : OTHER_LINE_SEPARATOR_ID );
		}
		
		return jComboBoxLineSeparator;
	}
	
	private JPanel getJPanelButtonsConfig() {
		if ( jPanelButtonsConfig == null ) {
			jPanelButtonsConfig =new JPanel();
			jPanelButtonsConfig.setLayout( new GridBagLayout() );
			GridBagConstraints cc =new GridBagConstraints();
			jPanelButtonsConfig.setBorder( BorderFactory.createTitledBorder( "Buttons configuration" ) );
			
			cc.gridx =0;
			cc.gridy =0;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.25;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.WEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelButtonsConfig.add( new JLabel("New point button"), cc );
			
			jTextFieldNewPoint =new JTextField();
			cc.gridx =0;
			cc.gridy =1;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.25;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.WEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelButtonsConfig.add( jTextFieldNewPoint, cc );
			jTextFieldNewPoint.setText( ds.getNewPointButton() );
			
			cc.gridx =0;
			cc.gridy =2;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.25;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.WEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelButtonsConfig.add( new JLabel("Close polygon button"), cc );
			
			jTextFieldClosePolygon =new JTextField();
			cc.gridx =0;
			cc.gridy =3;
			cc.gridheight =1;
			cc.gridwidth =1;
			cc.weightx =.25;
			cc.weighty =.0;
			cc.anchor =GridBagConstraints.WEST;
			cc.insets = new Insets(5,5,5,5);
			cc.fill =GridBagConstraints.HORIZONTAL;
			jPanelButtonsConfig.add( jTextFieldClosePolygon, cc );
			jTextFieldClosePolygon.setText( ds.getClosePolygonButton() );
		}
		
		return jPanelButtonsConfig;
			
	}
	
	private Double verifyDouble( String text, String msg ) {
		Double dbl =null;
		
		try {
			dbl =Double.parseDouble( text );
			
		} catch (Exception e ) {
			
			StringBuilder message =new StringBuilder( "<HTML>" )
										.append( text ).append( " is not a valid value for " ).append( msg )
										.append( "</HTML>" );

			JOptionPane.showMessageDialog( null, message.toString(), "Coordinates system", JOptionPane.ERROR_MESSAGE );
		}
		
		return dbl;
	}
	
	public boolean save() {
		
		boolean ret =false;
		
		Double xMin =verifyDouble( jTextFieldMinX.getText(), "X Min" );
		Double yMin =verifyDouble( jTextFieldMinY.getText(), "Y Min" );		
		Double xMax =verifyDouble( jTextFieldMaxX.getText(), "X Max" );	
		Double yMax =verifyDouble( jTextFieldMaxY.getText(), "Y Max" );			

		if ( xMin != null && yMin != null && xMax != null && yMax != null ) {
		
			ds.setBaudRate( Integer.valueOf( (String)jComboBoxPortSpeed.getSelectedItem() ) );
			ds.setCommunicationPort( (String)jComboBoxPortSelection.getSelectedItem() );	
			ds.setDataBitsConfiguration( Integer.parseInt( ((ConfigPair)(jComboBoxDataBits.getSelectedItem())).getId() ) );
			ds.setParity( Integer.parseInt( ((ConfigPair)(jComboBoxParity.getSelectedItem())).getId() ) );
			ds.setStopBits( Integer.parseInt( ((ConfigPair)(jComboBoxStopBits.getSelectedItem())).getId() ) );
			
			ds.setXMin( xMin );
			ds.setYMin( yMin );	
			ds.setXMax( xMax );
			ds.setYMax( yMax );
			
			String fieldSep =((ConfigPair)(getJComboBoxFieldSeparator().getSelectedItem())).getId();
			if ( "".equals( fieldSep ) ) {
				fieldSep =jTextFieldSeparator.getText();
			}			
			ds.setFieldSeparator( fieldSep );
			
			String lineSep =((ConfigPair)(getJComboBoxLineSeparator().getSelectedItem())).getId();
			if ( "".equals( lineSep ) ) {
				lineSep =jTextFieldLineSeparator.getText();
			}
			ds.setLineSeparator( lineSep );
			
			ds.setNewPointButton( jTextFieldNewPoint.getText() );
			ds.setClosePolygonButton( jTextFieldClosePolygon.getText() );
			
			ret =true;
		}
		
		return ret;
	}
	
	/**
	 * 
	 * @return A list of available ports in the current system
	 */
	@SuppressWarnings("unchecked")
	public String[] getAvailablePorts() throws Exception {
		List<String> portList =new LinkedList<String>();
		Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
		
		while( portEnum.hasMoreElements() ){
			portList.add( portEnum.nextElement().getName() );
		}
		
		if( portList.size() == 0 ){
			portList.add( "No communication port found!");
		}
		
		String[] ports =new String[ portList.size() ];
		portList.toArray( ports );
		
		return ports;
	}
	
	public int getIdxForId( String id, ConfigPair[] entries ) {
		int idxFound =-1;
		for( int idx =0; idx < entries.length; idx++ ) {
			if ( entries[ idx ].getId().equals( id ) ) {
				idxFound =idx;
				break;
			}
		}
		
		return idxFound;
	}

}
